home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oh!X 2001 Spring
/
Oh!X 2001 Spring Special CD-ROM (Japan).7z
/
Oh!X 2001 Spring Special CD-ROM (Japan) (Track 1).bin
/
JAVA
/
spman040.lzh
/
ShootSaucer.java
< prev
next >
Wrap
Text File
|
1996-06-06
|
10KB
|
341 lines
import java.applet.Applet;
import java.applet.AudioClip;
import java.lang.Math;
import java.util.Random;
import java.util.Date;
import java.awt.*;
public class ShootSaucer extends Applet implements Runnable {
static final int ENEMY = 6; // 敵は最大6機
static final int WIDTH = 320, HEIGHT = 240; // 背景サイズ
SpriteCanvas sc; // スプライトキャンバス
int mx, my, mbx, mby; // 自分の座標とミサイルの座標
int ex[] = new int[ENEMY], ey[] = new int[ENEMY]; // 敵の座標
int ebx[] = new int[ENEMY], eby[] = new int[ENEMY]; // 敵の弾の座標
int count[] = new int[ENEMY], direct[] = new int[ENEMY]; // 敵の回転
int edx[] = new int[ENEMY], edy[] = new int[ENEMY]; // 敵の弾の速度
int score; // スコア
boolean mbf, ef[] = new boolean[ENEMY], ebf[] = new boolean[ENEMY];
// 自分のミサイル、敵、敵の弾の表示フラグ
boolean up, down, left, right, space; // キー入力フラグ
Thread thread=null;
MediaTracker mt;
Random aRandom = new Random();
Math aMath;
Label Score;
boolean play = false; // ゲーム中フラグ
AudioClip gun, bomb, wow, hit[] = new AudioClip[4];
public void init(){
Image image;
int i;
// 効果音読み込み
gun = getAudioClip( getDocumentBase(), "audio/gun.au" );
bomb = getAudioClip( getDocumentBase(), "audio/bomb.au" );
wow = getAudioClip( getDocumentBase(), "audio/wow.au" );
hit[0] = getAudioClip( getDocumentBase(), "audio/comeon.au" );
hit[1] = getAudioClip( getDocumentBase(), "audio/get.au" );
hit[2] = getAudioClip( getDocumentBase(), "audio/iyao.au" );
hit[3] = getAudioClip( getDocumentBase(), "audio/wao.au" );
// スプライトキャンバス作成
// パターンは、自機、ミサイル、敵6パターン、敵の弾、爆発
// プレーンは、自機、ミサイル、敵6機、敵の弾6発
sc = new SpriteCanvas( 1+1+6+1+1, 1+1+ENEMY+ENEMY, WIDTH, HEIGHT, this );
setLayout( new BorderLayout() );
score = 0;
Score = new Label( "SCORE "+score, Label.CENTER );
add( "Center", sc );
add( "North", Score );
add( "South", new Button( "Start" ) );
mt = new MediaTracker( this );
image = getImage( getDocumentBase(), "image/earth.gif" ); // 背景
mt.addImage( image, 0 );
sc.WaitLoadImage( mt, 0 ); // 読み込むまでスプライトを表示しない
sc.SetBGImage( image ); // 背景に設定
image = getImage( getDocumentBase(), "image/Fighter.gif" ); // 自機
mt.addImage( image, 0 );
sc.Define( 0, image ); // パターン0に設定
image = getImage( getDocumentBase(), "image/Missile.gif" ); // ミサイル
mt.addImage( image, 0 );
sc.Define( 1, image ); // パターン1に設定
for( i=1; i<=6; i++ ){
// 敵の回転6パターン
image = getImage( getDocumentBase(), "image/Enemy"+i+".gif" );
mt.addImage( image, 0 );
sc.Define( i+1, image ); // パターン2~7に設定
}
image = getImage( getDocumentBase(), "image/Bomb.gif" ); // 敵の弾
mt.addImage( image, 0 );
sc.Define( 8, image ); // パターン8に設定
image = getImage( getDocumentBase(), "image/Crush.gif" ); // 爆発
mt.addImage( image, 0 );
sc.Define( 9, image ); // パターン9に設定
for( i=0; i<ENEMY; i++ ) ef[i] = ebf[i] = false;
// 速いインタプリタなら、下のコメントを取った方がいいかも
// sc.SetClipMode( true );
}
public void start(){
if( thread==null ){
thread = new Thread( this );
thread.start();
}
}
public void stop(){
if( thread!=null ){
thread.stop();
thread = null;
}
}
public void run(){
try {
mt.waitForID( 0 );
} catch( InterruptedException e ){
return;
}
while( true ){
try {
Thread.sleep( 50 );
} catch( InterruptedException e ){
break;
}
for( int i=0; i<ENEMY; i++ ){ // 敵の動き
int r = aMath.abs(aRandom.nextInt());
if( ef[i]==false ){ // 敵は出ていない
sc.Hide( i+ENEMY+2, i+ENEMY+2 );
if( (r&0x7f)<=score>>3 ) InitEnemy( i ); // 出現
} else {
switch( direct[i] ){ // 回転の向き
case 1:// 左向き
count[i]++;
if( count[i]>=6 ) count[i] = 0;
sc.Set( i+ENEMY+2, count[i]+2 ); // 回転
ex[i] -= 2;
break;
case 2:// 右向き
count[i]--;
if( count[i]<0 )count[i] = 5;
sc.Set( i+ENEMY+2, count[i]+2 ); // 回転
ex[i] += 2;
break;
default:// 回転してない
switch( r&0x3f ){
case 1: // 左向き回転させる
direct[i] = 1;
count[i] = 1;
// 弾発射
if( ((r>>8)&0xff)<score ) Bomb( i );
break;
case 2: // 右向き回転させる
direct[i] = 2;
count[i] = 5;
// 弾発射
if( ((r>>8)&0xff)<score ) Bomb( i );
break;
}
}
}
if( ef[i] ){
ey[i] += 4;
if( ey[i]>240 ){ // 画面から出ていった
ef[i] = false;
sc.Hide( i+ENEMY+2, i+ENEMY+2 ); // スプライト非表示
} else sc.Move( i+ENEMY+2, ex[i], ey[i] ); // 移動
}
if( ebf[i] ){
ebx[i] += edx[i];
eby[i] += edy[i];
if( ebx[i]<-32 || ebx[i]>WIDTH ||
eby[i]<-32 || eby[i]>HEIGHT ){ // 弾が出ていった
sc.Hide( i+2, i+2 ); // スプライト非表示
ebf[i] = false;
} else {
sc.Move( i+2, ebx[i], eby[i] ); // 移動
}
}
}
if( play ){ // ゲーム中
// キー判定
if( up && !down ) if( my>4 ) my -= 4;
if( down && !up ) if( my<HEIGHT-32-4 ) my += 4;
if( left && !right ) if( mx>4 ) mx -= 4;
if( right && !left ) if( mx<WIDTH-32-4 ) mx += 4;
sc.Move( 0, mx, my ); // 移動
// ミサイルが出ていないときにスペースキーを押した
if( space && !mbf ){
mbx = mx;
mby = my;
mbf = true;
sc.Set( 1, 1 ); // ミサイルプレーンをセット
sc.Show( 1, 1 ); // ミサイルプレーンを表示
gun.play(); // SE
}
if( mbf ){ // ミサイルが出ている
mby -= 16;
if( mby<-32 ){
sc.Hide( 1, 1 ); // 画面から出ていった
mbf = false;
} else {
if( HitCheck() ){ // 敵との当たり判定
mbf = false;
sc.Hide( 1, 1 ); // ヒットしたらミサイルも消す
} else sc.Move( 1, mbx, mby ); // 移動
}
}
if( CrushCheck() ){ // 自機の敵および敵の弾との当たり判定
sc.Set( 0, 9 ); // 死んじゃった
sc.Hide( 1, 1 );
play = false;
}
}
sc.Draw(); // スプライト描画
}
}
void InitEnemy( int n ){ // 敵の初期化
ex[n] = aMath.abs(aRandom.nextInt())%(WIDTH-32);
ey[n] = -32;
ef[n] = true;
direct[n] = 0;
sc.Set( n+ENEMY+2, 2 ); // プレーンセット
sc.Show( n+ENEMY+2, n+ENEMY+2 ); // 表示
}
boolean HitCheck() // ミサイルと敵の当たり判定
{
boolean result = false;
for( int i=0; i<ENEMY; i++ ){
if( ef[i] ){ // 敵は出ている?
if( ex[i]>mbx-16 && ex[i]<mbx+16 &&
ey[i]>mby-20 && ey[i]<mby+20 ){ // 当たり
ef[i] = false;
sc.Set( i+ENEMY+2, 9 ); // 敵プレーンに爆発パターンをセット
score += 1;
Score.setText( "SCORE "+score );
result = true;
int r = aMath.abs(aRandom.nextInt());
hit[r%4].play(); // SE
if( (r&0xf)<score>>3 ) Bomb( i ); // 打ち返してきた
break;
}
}
}
return result;
}
boolean CrushCheck() // 自機の当たり判定
{
boolean result = false;
for( int i=0; i<ENEMY; i++ ){ // 敵との判定
if( ef[i] ){ // 敵は出ている?
if( ex[i]>mx-20 && ex[i]<mx+20 &&
ey[i]>my-20 && ey[i]<my+20 ){ // 当たり
ef[i] = false;
sc.Set( i+ENEMY+2, 9 ); // 敵プレーンに爆発パターンをセット
score += 1;
Score.setText( "SCORE "+score );
result = true;
bomb.play(); // ドカーン
break;
}
}
if( ebf[i] ){ // 敵の弾は出ている?
if( ebx[i]>mx-16 && ebx[i]<mx+16 &&
eby[i]>my-16 && eby[i]<my+16 ){ // 当たり
ebf[i] = false;
sc.Hide( i+2, i+2 ); // 弾を消す
result = true;
bomb.play(); // ドカーン
break;
}
}
}
return result;
}
void Bomb( int i ) // 敵の弾発射
{
// 敵の弾が発射済みかゲーム中でなければ発射しない
if( ebf[i] || !play ) return;
ebx[i] = ex[i];
eby[i] = ey[i];
int dx, dy, ux, uy;
// 適当に弾の向き設定
dx = mx-ebx[i];
dy = my-eby[i];
ux = dx>=0?dx:-dx;
uy = dy>=0?dy:-dy;
if( ux>uy ){
edx[i] = 5;
edy[i] = 3;
} else {
edx[i] = 3;
edy[i] = 5;
}
if( dx<0 ) edx[i] = -edx[i];
if( dy<0 ) edy[i] = -edy[i];
ebf[i] = true;
sc.Set( i+2, 8 ); // 弾プレーンセット
sc.Show( i+2, i+2 ); // 表示
wow.play(); // SE
}
public boolean keyDown( Event e, int key ){
switch( key ){
case 1004://↑
up = true;
break;
case 1005://↓
down = true;
break;
case 1006:// ←
left = true;
break;
case 1007:// →
right = true;
break;
case ' ':
space = true;
break;
}
return true;
}
public boolean keyUp( Event e, int key ){
switch( key ){
case 1004://↑
up = false;
break;
case 1005://↓
down = false;
break;
case 1006:// ←
left = false;
break;
case 1007:// →
right = false;
break;
case ' ':
space = false;
break;
}
return true;
}
public boolean action( Event e, Object o ){
if( e.target instanceof Button ){
if( play==false ){ // ゲームスタート
play = true;
score = 0;
Score.setText( "SCORE "+score );
for( int i=0; i<ENEMY; i++ ){ // 敵の初期化
ef[i] = false;
ebf[i] = false;
}
sc.Hide(); // 取りあえず全部隠しといて
mx = (WIDTH-32)/2;
my = HEIGHT-32-32;
sc.Set( 0, 0 ); // 自機プレーンセット
sc.Set( 1, 1 ); // ミサイルプレーンセット
sc.Move( 0, mx, my ); // 自機の座標設定
sc.Show( 0, 0 ); // 自機表示
up = down = left = right = space = false;
mbf = false;
}
return true;
}
return false;
}
}